Imports System.Collections.Generic

Namespace CardGameFramework

    Public Class Deck
        'Creates a list of cards
        Protected _cards As New List(Of Card)
        'Returns the card at the given position
        Default Public ReadOnly Property _position(ByVal position As Integer) As Card
            Get
                Return _cards(position)
            End Get
        End Property

        ''' <summary>
        ''' One complete deck with every face value and suit
        ''' </summary>
        ''' <remarks></remarks>
        Public Sub New()
            _cards.Add(New Card(Suit.Clubs, FaceValue.Ace, 1, True))
            _cards.Add(New Card(Suit.Clubs, FaceValue.Two, 2, True))
            _cards.Add(New Card(Suit.Clubs, FaceValue.Three, 3, True))
            _cards.Add(New Card(Suit.Clubs, FaceValue.Four, 4, True))
            _cards.Add(New Card(Suit.Clubs, FaceValue.Five, 5, True))
            _cards.Add(New Card(Suit.Clubs, FaceValue.Six, 6, True))
            _cards.Add(New Card(Suit.Clubs, FaceValue.Seven, 7, True))
            _cards.Add(New Card(Suit.Clubs, FaceValue.Eight, 8, True))
            _cards.Add(New Card(Suit.Clubs, FaceValue.Nine, 9, True))
            _cards.Add(New Card(Suit.Clubs, FaceValue.Ten, 10, True))
            _cards.Add(New Card(Suit.Clubs, FaceValue.Jack, 11, True))
            _cards.Add(New Card(Suit.Clubs, FaceValue.Knight, 12, True))
            _cards.Add(New Card(Suit.Clubs, FaceValue.Queen, 13, True))
            _cards.Add(New Card(Suit.Clubs, FaceValue.King, 14, True))
            _cards.Add(New Card(Suit.Spades, FaceValue.Ace, 1, True))
            _cards.Add(New Card(Suit.Spades, FaceValue.Two, 2, True))
            _cards.Add(New Card(Suit.Spades, FaceValue.Three, 3, True))
            _cards.Add(New Card(Suit.Spades, FaceValue.Four, 4, True))
            _cards.Add(New Card(Suit.Spades, FaceValue.Five, 5, True))
            _cards.Add(New Card(Suit.Spades, FaceValue.Six, 6, True))
            _cards.Add(New Card(Suit.Spades, FaceValue.Seven, 7, True))
            _cards.Add(New Card(Suit.Spades, FaceValue.Eight, 8, True))
            _cards.Add(New Card(Suit.Spades, FaceValue.Nine, 9, True))
            _cards.Add(New Card(Suit.Spades, FaceValue.Ten, 10, True))
            _cards.Add(New Card(Suit.Spades, FaceValue.Jack, 11, True))
            _cards.Add(New Card(Suit.Spades, FaceValue.Knight, 12, True))
            _cards.Add(New Card(Suit.Spades, FaceValue.Queen, 13, True))
            _cards.Add(New Card(Suit.Spades, FaceValue.King, 14, True))
            _cards.Add(New Card(Suit.Hearts, FaceValue.Ace, 10, True))
            _cards.Add(New Card(Suit.Hearts, FaceValue.Two, 9, True))
            _cards.Add(New Card(Suit.Hearts, FaceValue.Three, 8, True))
            _cards.Add(New Card(Suit.Hearts, FaceValue.Four, 7, True))
            _cards.Add(New Card(Suit.Hearts, FaceValue.Five, 6, True))
            _cards.Add(New Card(Suit.Hearts, FaceValue.Six, 5, True))
            _cards.Add(New Card(Suit.Hearts, FaceValue.Seven, 4, True))
            _cards.Add(New Card(Suit.Hearts, FaceValue.Eight, 3, True))
            _cards.Add(New Card(Suit.Hearts, FaceValue.Nine, 2, True))
            _cards.Add(New Card(Suit.Hearts, FaceValue.Ten, 1, True))
            _cards.Add(New Card(Suit.Hearts, FaceValue.Jack, 11, True))
            _cards.Add(New Card(Suit.Hearts, FaceValue.Knight, 12, True))
            _cards.Add(New Card(Suit.Hearts, FaceValue.Queen, 13, True))
            _cards.Add(New Card(Suit.Hearts, FaceValue.King, 14, True))
            _cards.Add(New Card(Suit.Diamonds, FaceValue.Ace, 10, True))
            _cards.Add(New Card(Suit.Diamonds, FaceValue.Two, 9, True))
            _cards.Add(New Card(Suit.Diamonds, FaceValue.Three, 8, True))
            _cards.Add(New Card(Suit.Diamonds, FaceValue.Four, 7, True))
            _cards.Add(New Card(Suit.Diamonds, FaceValue.Five, 6, True))
            _cards.Add(New Card(Suit.Diamonds, FaceValue.Six, 5, True))
            _cards.Add(New Card(Suit.Diamonds, FaceValue.Seven, 4, True))
            _cards.Add(New Card(Suit.Diamonds, FaceValue.Eight, 3, True))
            _cards.Add(New Card(Suit.Diamonds, FaceValue.Nine, 2, True))
            _cards.Add(New Card(Suit.Diamonds, FaceValue.Ten, 1, True))
            _cards.Add(New Card(Suit.Diamonds, FaceValue.Jack, 11, True))
            _cards.Add(New Card(Suit.Diamonds, FaceValue.Knight, 12, True))
            _cards.Add(New Card(Suit.Diamonds, FaceValue.Queen, 13, True))
            _cards.Add(New Card(Suit.Diamonds, FaceValue.King, 14, True))
            _cards.Add(New Card(Suit.Trumps, FaceValue.Ace, 100, True))
            _cards.Add(New Card(Suit.Trumps, FaceValue.Two, 200, True))
            _cards.Add(New Card(Suit.Trumps, FaceValue.Three, 300, True))
            _cards.Add(New Card(Suit.Trumps, FaceValue.Four, 400, True))
            _cards.Add(New Card(Suit.Trumps, FaceValue.Five, 500, True))
            _cards.Add(New Card(Suit.Trumps, FaceValue.Six, 600, True))
            _cards.Add(New Card(Suit.Trumps, FaceValue.Seven, 700, True))
            _cards.Add(New Card(Suit.Trumps, FaceValue.Eight, 800, True))
            _cards.Add(New Card(Suit.Trumps, FaceValue.Nine, 900, True))
            _cards.Add(New Card(Suit.Trumps, FaceValue.Ten, 1000, True))
            _cards.Add(New Card(Suit.Trumps, FaceValue.Eleven, 1100, True))
            _cards.Add(New Card(Suit.Trumps, FaceValue.Twelve, 1200, True))
            _cards.Add(New Card(Suit.Trumps, FaceValue.Thirteen, 1300, True))
            _cards.Add(New Card(Suit.Trumps, FaceValue.Fourteen, 1400, True))
            _cards.Add(New Card(Suit.Trumps, FaceValue.Fifteen, 1500, True))
            _cards.Add(New Card(Suit.Trumps, FaceValue.Sixteen, 1600, True))
            _cards.Add(New Card(Suit.Trumps, FaceValue.Seventeen, 1700, True))
            _cards.Add(New Card(Suit.Trumps, FaceValue.Eighteen, 1800, True))
            _cards.Add(New Card(Suit.Trumps, FaceValue.Nineteen, 1900, True))
            _cards.Add(New Card(Suit.Trumps, FaceValue.Twenty, 2000, True))
            _cards.Add(New Card(Suit.Trumps, FaceValue.TwentyOne, 2100, True))
            _cards.Add(New Card(Suit.Fool, FaceValue.Fool, 0, True))
        End Sub

        ''' <summary>
        ''' Draws one card and removes it from the deck
        ''' </summary>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Function Draw() As Card
            Dim card As Card = _cards(0)
            _cards.RemoveAt(0)
            Return card
        End Function

        ''' <summary>
        ''' Shuffles the cards in the deck
        ''' </summary>
        ''' <remarks></remarks>
        Public Sub Shuffle()
            Dim random As New Random
            Dim i As Integer = 0
            While i < _cards.Count
                Dim index1 As Integer = i
                Dim index2 As Integer = random.Next(_cards.Count)
                SwapCard(index1, index2)
                i = i + 1
            End While
        End Sub

        ''' <summary>
        ''' Swaps the placement of two cards
        ''' </summary>
        ''' <param name="index1"></param>
        ''' <param name="index2"></param>
        ''' <remarks></remarks>
        Private Sub SwapCard(ByVal index1 As Integer, ByVal index2 As Integer)
            Dim card As Card = _cards(index1)
            _cards(index1) = _cards(index2)
            _cards(index2) = card
        End Sub
    End Class
End Namespace